﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CaseScenario_Chapter1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Doctor drRay = new Doctor("physician", 10000.00, 45, "Beltmore Avanue", "Raymond Salles");
                Doctor drSimmon = new Doctor("pediatric", 20000.00, 55, "Disney", "John Simmons");

                //using an array to gather all the doctors.
                Doctor[] doctors = { drRay, drRay };

                Subscriber pedroPinto = new Subscriber("randomInformation", SubscriptionPlan.FullAssist, 24, "Sao Roque", "Pedro Pinto");

                Mailing<Doctor> mailingDrSimmon = new Mailing<Doctor>(drSimmon);

                Console.WriteLine(mailingDrSimmon.ToString());

                Mathmathics a1 = new Mathmathics(0.0);
                Mathmathics a2 = new Mathmathics(1.0);
                Mathmathics a3 = new Mathmathics(6.4);

                Mathmathics[] operands = { a1, a2, a3 };

                Array.Sort(operands);

                foreach (Mathmathics obj in operands)
                {
                    Console.WriteLine(obj.operand.ToString());
                }

                Console.WriteLine(Convert.ToBoolean(a1));

                a1.Dispose();

                Console.ReadKey();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }

    class Mailing<T> where T : Person
    {
        public T t;

        public Mailing(T t)
        {
            this.t = t;
        }

        public override string ToString()
        {
            return "sending a mail to the adress " + t.adress + ", to Mr/Mrs " + t.name;
        }
    }

    class Person
    {
        public int age;
        public string adress;
        public string name;

        public Person(int age, string adress, string name)
        {
            this.age = age;
            this.adress = adress;
            this.name = name;
        }
    }

    class Doctor : Person
    {
        public string specialty;
        public double contractValue;

        public Doctor(string specialty, double contractValue, int age, string adress, string name)
            : base(age, adress, name)
        {
            this.specialty = specialty;
            this.contractValue = contractValue;
        }

    }

    public enum SubscriptionPlan { FullAssist, PartialAssist };

    class Subscriber : Person
    {
        public string paymentInformation;
        private SubscriptionPlan plan;
        public SubscriptionPlan Plan
        {
            get
            {
                return this.plan;
            }
            set
            {
                this.plan = value;
            }
        }

        public Subscriber(string paymentInformation, SubscriptionPlan subscriptionPlan, int age, string adress, string name)
            : base(age, adress, name)
        {
            this.paymentInformation = paymentInformation;
            this.Plan = subscriptionPlan;
        }
    }

    class Mathmathics : IComparable, IConvertible, IDisposable
    {
        public double operand = 1;

        public string name;

        public Mathmathics(double value)
        {
            this.operand = value;
        }

        public double GetDouble()
        {
            return this.operand;
        }

        #region IComparable Members

        int IComparable.CompareTo(object obj)
        {
            if (obj is Mathmathics)
            {
                Mathmathics aux = (Mathmathics)obj;
                return this.operand.CompareTo(aux.operand);
            }
            else
            {
                throw new Exception("Object is not from Mathmethics class");
            }
        }

        #endregion

        #region IConvertible Members

        public TypeCode GetTypeCode()
        {
            return TypeCode.Object;
        }

        public bool ToBoolean(IFormatProvider provider)
        {
            if (this.operand != 0.0)
                return true;
            else
                return false;
        }

        public byte ToByte(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public char ToChar(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public DateTime ToDateTime(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public decimal ToDecimal(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public double ToDouble(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public short ToInt16(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public int ToInt32(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public long ToInt64(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public sbyte ToSByte(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public float ToSingle(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public string ToString(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public object ToType(Type conversionType, IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public ushort ToUInt16(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public uint ToUInt32(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        public ulong ToUInt64(IFormatProvider provider)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~Mathmathics()
        {
            Dispose(false);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                this.name = null;
            }
        }

        #endregion
    }
}
